In computer science, the term value type is commonly used to refer to one of two kinds of data types: Types of values or Types of objects with deep copy semantics.
Contents |
Elements of Programming[1] defines a value to be a sequence of bits, called datum, together with its interpretation. A value type, then, is a correspondence between a set of data and a set of abstract or concrete entities sharing characteristic attributes. The set of entities is sometimes called a species. For example, a value type—call it small_int_value
— can establish the correspondence between a sequence of 16 bits and integers values from -32,768 to +32,767 through a two's complement representation.
Value types do not include constraints on how their values are stored. E.g., the type small_int_value
in the example above does not determine byte order, alignment, or even the number of 8-bit bytes used to store the 16 bits of the value type's representation. Since the values underpinning value types are not stored, value types also do not include a notion of mutation. A type that does determine constraints for storage in random-access memory is often called an object type.
Pure functional programming languages do not model state and their types are therefore value types in the sense described here.
In contrast, imperative programming languages require a notion of object type. Imperative programming languages also deal with values, but their type systems often do not distinguish the types of values from the types of objects. Instead, the context of an expressions determines whether the storage characteristics associated with an object type plays a role or not. For example, in C and C++, expressions are treated as lvalues or rvalues—the latter can be thought of as having value types.
Some programming languages—notably C#[2]—use the term value type to refer to the types of objects for which assignment has deep copy semantics (as opposed to reference types, which have shallow copy semantics). For example:
int i1 = 42; // "int" is a value type. int i2 = i1; // i2 uses distinct storage for its value: // the value of i1 is "deep-copied" into i2. object o1 = i1; // "Boxing" (see below) from the value type "int" // to a reference type compatible with "object". object o2 = o1; // Since o1 and o2 have reference type, they // now refer to the same value storage; i.e., // o1 is "shallow-copied" into o2.
Other programming languages—e.g., Java—do not formally define the term value type, but their practitioners informally use the term to refer to types with deep copy semantics (such as Java's primitive types).
Programming languages that distinguish between value types and reference types typically offer a mechanism, called boxing, to wrap some or all of their value types in reference types. This permits the use of value types in contexts expecting reference types. The converse process (to unwrap the value type) is known as unboxing.